package com.runa.monitor.platinterface.platService;

import com.alibaba.fastjson.JSON;
import com.rn.smart.command.dto.meter.MeterBase;
import com.rn.smart.command.dto.meter.RunaMeter;
import com.rn.smart.command.dto.valve.ValveBase;
import com.rn.smart.command.dto.valve.contro.RunaValve;
import com.rn.smart.command.dto.valve.contro.YiLinValve;
import com.rn.smart.command.dto.valve.contro.ZheDaValve;
import com.rn.smart.command.dto.valve.read.RunaReadValve;
import com.runa.monitor.comm.constants.ResultConstants;
import com.runa.monitor.comm.dto.Meter;
import com.runa.monitor.comm.dto.Node;
import com.runa.monitor.comm.dto.TempPanel;
import com.runa.monitor.comm.dto.Valve;
import com.runa.monitor.comm.dto.newComm.AsynResult;
import com.runa.monitor.comm.dto.newComm.HotMeterVO;
import com.runa.monitor.comm.dto.newComm.PanelVO;
import com.runa.monitor.comm.dto.newComm.ValveVO;
import com.runa.monitor.comm.entity.CommMeter;
import com.runa.monitor.comm.entity.CommNetEquipment;
import com.runa.monitor.comm.entity.CommPanel;
import com.runa.monitor.comm.entity.CommValve;
import com.runa.monitor.comm.enums.NetEquTypeEnum;
import com.runa.monitor.comm.enums.RegionTypeEnum;
import com.runa.monitor.comm.pojo.NBOrder;
import com.runa.monitor.platinterface.dispatch.conn.gen.*;
import com.runa.monitor.platinterface.extend.flightControl.FlightControlService;
import com.runa.monitor.platinterface.extend.hmy.HmyValveService;
import com.runa.monitor.platinterface.mqtt.MqttUtil;
import com.runa.monitor.platinterface.netservice.equipment.dtu.fourG.FourGValveDtuService;
import com.runa.monitor.platinterface.platService.gateway.BuildGatewayService;
import com.runa.monitor.platinterface.platService.pojo.GatewayDeviceParameter;
import com.runa.persistence.CollectionUtil;
import com.runa.persistence.StringUtil;
import com.runa.persistence.entity.apportion.ApportionValveControlParam;
import com.runa.persistence.repository.CommNetEquipmentRepository;
import com.runa.persistence.repository.CommValveRepository;
import com.runa.persistence.service.CommMeterService;
import com.runa.persistence.service.CommNbCmdService;
import com.runa.persistence.service.CommPanelService;
import com.runa.persistence.service.CommValveService;
import com.runa.persistence.util.LogUtil;
import com.runa.protocol.dto.BatchValveDTO;
import com.runa.rccprotocol.dto.equdata.EquData;
import com.runa.rccprotocol.dto.param.MeterReadingCycle;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhuj
 */
@Slf4j
@Service
public class InterfaceService {

    @Resource
    private NetEquService netEquService;
    @Resource
    private BuildGatewayService buildGatewayService;
    @Resource
    private CommNetEquipmentRepository commNetEquipmentRepository;
    @Resource
    private CommMeterService commMeterService;
    @Resource
    private CommValveService commValveService;
    @Resource
    private CommPanelService commPanelService;
    @Resource
    private CommValveRepository commValveRepository;
    @Resource
    private RepositoryService repositoryService;

    //立即抄表
    public void readFmuNow(String id, String taskNo, String holdInfo, Integer priority) {
        Optional<CommNetEquipment> commNetEquipment = commNetEquipmentRepository.findById(id);
        if (!commNetEquipment.isPresent()) {
            log.error("无此档案:" + id);
            MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, MqttUtil.topicOfNoneContent, id);
            return;
        }
        netEquService.readFmuNow(commNetEquipment.get(), taskNo, holdInfo, priority);
    }

    //下发档案
    public void rccSentEquArchive(String id, String taskNo, List archives, String holdInfo, Integer priority) {
        Optional<CommNetEquipment> commNetEquipment = commNetEquipmentRepository.findById(id);
        if (!commNetEquipment.isPresent()) {
            log.error("无此档案: {}", id);
            MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, MqttUtil.topicOfNoneContent, id);
            return;
        }
        netEquService.setNodeEquArchive(commNetEquipment.get(), taskNo, holdInfo, priority, archives);
    }

    //清除档案
    public void rccClearEquArchive(String id, String taskNo, String holdInfo, Integer priority) {
        Optional<CommNetEquipment> commNetEquipment = commNetEquipmentRepository.findById(id);
        if (!commNetEquipment.isPresent()) {
            log.error("无此档案: {}", id);
            MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, MqttUtil.topicOfNoneContent, id);
            return;
        }
        netEquService.rccClearEquArchive(commNetEquipment.get(), taskNo, holdInfo, priority);
    }

    //读取档案
    public void readEquArchive(String id, String taskNo, List<Integer> indexes, String holdInfo, Integer priority) {
        Optional<CommNetEquipment> commNetEquipment = commNetEquipmentRepository.findById(id);
        if (!commNetEquipment.isPresent()) {
            log.error("无此档案:" + id);
            MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, com.runa.monitor.comm.dto.newComm.Archive.TOPIC, id);
            return;
        }
        netEquService.readEquArchive(commNetEquipment.get(), taskNo, holdInfo, priority, indexes);
    }


    //设定抄读周期
    public void setMeterReadingCycleParameter(String id, String taskNo, GatewayDeviceParameter gatewayDeviceParameter, String holdInfo, Integer priority) {
        Optional<CommNetEquipment> commNetEquipment = commNetEquipmentRepository.findById(id);
        if (!commNetEquipment.isPresent()) {
            log.error("无此档案: {}",  id);
            MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, MqttUtil.topicOfNoneContent, id);
            return;
        }
        if (NetEquTypeEnum.AI控制器.equals(commNetEquipment.get().getType())) {
            buildGatewayService.ctrlDeviceParameter(taskNo, holdInfo, commNetEquipment.get(), gatewayDeviceParameter, MqttUtil.topicOfNoneContent);
        } else {
            netEquService.setMeterReadingCycleParameter(commNetEquipment.get(), taskNo, holdInfo,
                    priority, new MeterReadingCycle(gatewayDeviceParameter.getMinuteOfCollectForHouse()));
        }

    }


    //读取抄读周期
    public void readMeterReadingCycleParameter(String serial, String taskNo, String holdInfo, Integer priority) {
        //先行验证
        CommNetEquipment commNetEquipment = repositoryService.getCommNetEquipmentByIdentity(serial);
        if (commNetEquipment == null) {
            log.error("无此档案:" + serial);
            MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, MqttUtil.topicOfNoneContent, serial);
            return;
        }
        if (NetEquTypeEnum.AI控制器 == commNetEquipment.getType()) {
            buildGatewayService.readMeterReadingCycleParameter(taskNo, holdInfo, commNetEquipment, "comm/net/period");
        } else {
            netEquService.readMeterReadingCycleParameter(commNetEquipment, taskNo, holdInfo, priority);
        }
    }


    //流量超限设定
    public void flowLimitSetting(String serial, String taskNo, Float value, Boolean priority, String holdInfo, Integer priorityT) {
        CommNetEquipment commNetEquipment = repositoryService.getCommNetEquipmentByIdentity(serial);
        if (commNetEquipment == null) {
            log.error("无此档案:" + serial);
            MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, MqttUtil.topicOfNoneContent, serial);
        }
    }

    public List<CommNetEquipment> batchQueryMeter(String taskNo, String holdInfo, List<String> nodeIdentityList) {
        ArrayList<String> nodeIds = nodeIdentityList.stream().distinct().collect(Collectors.toCollection(ArrayList::new));
        List<CommMeter> meters = commMeterService.getAllByIds(nodeIds);
        List<String> meterIds = meters.stream().map(CommMeter::getId).collect(Collectors.toList());
        for (String meterId : meterIds) {
            nodeIds.remove(meterId);
        }
        if (!nodeIds.isEmpty())
            nodeIds.forEach(s -> MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, HotMeterVO.TOPIC, s));
        if (meters.isEmpty()) return new ArrayList<>();
        //分组
        List<CommNetEquipment> commNetEquipmentList = new ArrayList<>();
//        //转换为网络设备维度
        meters.stream().filter(m -> StringUtil.isNotBlank(m.getNetEquipmentId()))
                .collect(Collectors.groupingBy(CommMeter::getNetEquipmentId)).forEach((commNetId, commMeters) -> {
            Optional<CommNetEquipment> optional = commNetEquipmentRepository.findById(commNetId);
            if (optional.isPresent()) {
                optional.get().setNodeList(commMeters.stream().map(meter -> {
                    try {
                        repositoryService.setCommMeterByNodeSerialForNetEqu(meter.getSerial(), optional.get().getId(), meter);
                        repositoryService.setCommMeterByNodeIndexForNetEqu(meter.getSequence(), optional.get().getId(), meter);
                    } catch (Exception e) {
                        log.error("", e);
                    }
                    return Meter.getMeter(meter);
                }).collect(Collectors.toList()));
                commNetEquipmentList.add(optional.get());
            } else {
                log.error("表数据异常，网络设备无此档案：" + commNetId);
                MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, HotMeterVO.TOPIC, commNetId);
            }
        });

        return commNetEquipmentList;
    }

    public List<CommNetEquipment> batchValve(String taskNo, String holdInfo, List<String> nodeIdentityList) {
        BatchValveDTO batchValveDTO = batchQueryValve(taskNo, holdInfo, nodeIdentityList);
        return batchValveDTO.getCommNetEquipmentList();
    }

    public List<Node> batchQueryFourGValve(String taskNo, String holdInfo, List<String> nodeIdentityList) {
        List<Node> nodeList = new ArrayList<>();
        ArrayList<String> nodeIds = new ArrayList<>(nodeIdentityList.stream().distinct().collect(Collectors.toList()));
        List<CommValve> valves = commValveService.getAllByIds(nodeIds);
        List<String> meterIds = valves.stream().map(CommValve::getId).collect(Collectors.toList());
        for (String meterId : meterIds) {
            nodeIds.remove(meterId);
        }
        if (!nodeIds.isEmpty())
            nodeIds.forEach(s -> MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, ValveVO.TOPIC, s));
        if (valves.isEmpty()) return nodeList;

        nodeList = valves.stream().map(v -> Valve.getValve(v)).collect(Collectors.toList());
        return nodeList;
    }

    public BatchValveDTO batchQueryValve(String taskNo, String holdInfo, List<String> nodeIdentityList) {
        BatchValveDTO batchValveDTO = new BatchValveDTO();
        ArrayList<String> nodeIds = new ArrayList<>(nodeIdentityList.stream().distinct().collect(Collectors.toList()));
        List<CommValve> valves = commValveService.getAllByIds(nodeIds);
        List<String> meterIds = valves.stream().map(CommValve::getId).collect(Collectors.toList());
        for (String meterId : meterIds) {
            nodeIds.remove(meterId);
        }
        if (!nodeIds.isEmpty())
            nodeIds.forEach(s -> MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, ValveVO.TOPIC, s));
        if (valves.isEmpty()) return batchValveDTO;

        List<CommNetEquipment> commNetEquipmentList = new ArrayList<>();

        valves.stream().filter(m -> StringUtil.isNotBlank(m.getNetEquipmentId()))
                .collect(Collectors.groupingBy(CommValve::getNetEquipmentId)).forEach((commNetId, commValves) -> {
                    Optional<CommNetEquipment> optional = commNetEquipmentRepository.findById(commNetId);
                    if (optional.isPresent()) {
                        optional.get().setNodeList(commValves.stream().map(valve -> {
                            try {
                                repositoryService.setCommValveByNodeSerialForNetEqu(valve.getSerial(), optional.get().getId(), valve);
                                repositoryService.setCommValveByNodeIndexForNetEqu(valve.getSequence(), optional.get().getId(), valve);
                            } catch (Exception e) {
                                log.error("", e);
                            }
                            return Valve.getValve(valve);
                        }).collect(Collectors.toList()));
                        commNetEquipmentList.add(optional.get());
                    } else {
                        log.error("表数据异常，网络设备无此档案：" + commNetId);
                        MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, HotMeterVO.TOPIC, commNetId);
                    }
                });
        batchValveDTO.setCommNetEquipmentList(commNetEquipmentList);

        List<Node> fourGValves = valves.stream()
                .filter(m -> StringUtil.isBlank(m.getNetEquipmentId()) && "CAT1".equalsIgnoreCase(m.getModel()))
                .map(Valve::getValve)
                .collect(Collectors.toList());
        batchValveDTO.setFourGValves(fourGValves);

        return batchValveDTO;
    }

    public List<CommNetEquipment> batchQueryPanel(String taskNo, String holdInfo, List<String> nodeIdentityList) {
        ArrayList<String> nodeIds = nodeIdentityList.stream().distinct().collect(Collectors.toCollection(ArrayList::new));
        List<CommPanel> panels = commPanelService.getAllByIds(nodeIds);
        List<String> meterIds = panels.stream().map(CommPanel::getId).collect(Collectors.toList());
        for (String meterId : meterIds) {
            nodeIds.remove(meterId);
        }
        if (!nodeIds.isEmpty())
            nodeIds.forEach(s -> MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, PanelVO.TOPIC, s));
        if (panels.isEmpty()) return new ArrayList<>();
        //分组
        List<CommNetEquipment> commNetEquipmentList = new ArrayList<>();
        panels.stream().filter(p -> StringUtil.isNotBlank(p.getNetEquipmentId()))
                .collect(Collectors.groupingBy(CommPanel::getNetEquipmentId)).forEach((commNetId, commPanels) -> {
                    Optional<CommNetEquipment> optional = commNetEquipmentRepository.findById(commNetId);
                    if (optional.isPresent()) {
                        optional.get().setNodeList(commPanels.stream().map(panel -> {
                            repositoryService.setCommPanelByNodeSerialForNetEqu(panel.getSerial(), optional.get().getId(), panel);
                            repositoryService.setCommPanelByNodeIndexForNetEqu(panel.getSequence(), optional.get().getId(), panel);
                            return TempPanel.getTempPanel(panel);
                        }).collect(Collectors.toList()));
                        commNetEquipmentList.add(optional.get());
                    } else {
                        log.error("表数据异常，网络设备无此档案：" + commNetId);
                        MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, HotMeterVO.TOPIC, commNetId);
                    }
                });

        return commNetEquipmentList;
    }

    public static void main(String[] args) {
        String s = "{\"commNetService\":{\"enable\":1,\"id\":18,\"name\":\"瑞纳_集中器\",\"port\":50001,\"protocol\":\"RUNA_FMU\",\"type\":\"被动呼叫\"},\"elecSerial\":\"050\",\"id\":\"NEQ6303\",\"model\":\"RC-ZNCL-02\",\"nodeList\":[{\"id\":\"HME447006\",\"index\":31,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852227\",\"statuteCode\":40},{\"id\":\"HME447007\",\"index\":32,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852366\",\"statuteCode\":40},{\"id\":\"HME447008\",\"index\":33,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"21200266\",\"statuteCode\":40},{\"id\":\"HME447009\",\"index\":34,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22851093\",\"statuteCode\":40},{\"id\":\"HME447010\",\"index\":35,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852417\",\"statuteCode\":40},{\"id\":\"HME447011\",\"index\":36,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852207\",\"statuteCode\":40},{\"id\":\"HME447012\",\"index\":37,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852055\",\"statuteCode\":40},{\"id\":\"HME447013\",\"index\":38,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852331\",\"statuteCode\":40},{\"id\":\"HME447014\",\"index\":39,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852297\",\"statuteCode\":40},{\"id\":\"HME447015\",\"index\":40,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852369\",\"statuteCode\":40},{\"id\":\"HME447016\",\"index\":41,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852198\",\"statuteCode\":40},{\"id\":\"HME447017\",\"index\":42,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852341\",\"statuteCode\":40},{\"id\":\"HME447018\",\"index\":43,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852151\",\"statuteCode\":40},{\"id\":\"HME447019\",\"index\":44,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852405\",\"statuteCode\":40},{\"id\":\"HME447020\",\"index\":45,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852344\",\"statuteCode\":40},{\"id\":\"HME447021\",\"index\":46,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852305\",\"statuteCode\":40},{\"id\":\"HME447022\",\"index\":47,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852398\",\"statuteCode\":40},{\"id\":\"HME447023\",\"index\":48,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852192\",\"statuteCode\":40},{\"id\":\"HME447024\",\"index\":49,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852295\",\"statuteCode\":40},{\"id\":\"HME447025\",\"index\":50,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852403\",\"statuteCode\":40},{\"id\":\"HME447026\",\"index\":51,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852352\",\"statuteCode\":40},{\"id\":\"HME447027\",\"index\":52,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852393\",\"statuteCode\":40},{\"id\":\"HME447028\",\"index\":53,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852418\",\"statuteCode\":40},{\"id\":\"HME447029\",\"index\":54,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852416\",\"statuteCode\":40},{\"id\":\"HME447030\",\"index\":55,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852368\",\"statuteCode\":40},{\"id\":\"HME447031\",\"index\":56,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852069\",\"statuteCode\":40},{\"id\":\"HME447032\",\"index\":57,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852356\",\"statuteCode\":40},{\"id\":\"HME447033\",\"index\":58,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852167\",\"statuteCode\":40},{\"id\":\"HME447034\",\"index\":59,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852436\",\"statuteCode\":40},{\"id\":\"HME447035\",\"index\":60,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852042\",\"statuteCode\":40},{\"id\":\"HME447036\",\"index\":61,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852050\",\"statuteCode\":40},{\"id\":\"HME447037\",\"index\":62,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852289\",\"statuteCode\":40},{\"id\":\"HME447038\",\"index\":1,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852150\",\"statuteCode\":40},{\"id\":\"HME447039\",\"index\":2,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852200\",\"statuteCode\":40},{\"id\":\"HME447040\",\"index\":3,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852003\",\"statuteCode\":40},{\"id\":\"HME447041\",\"index\":4,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852104\",\"statuteCode\":40},{\"id\":\"HME447042\",\"index\":5,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852354\",\"statuteCode\":40},{\"id\":\"HME447043\",\"index\":6,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852083\",\"statuteCode\":40},{\"id\":\"HME447044\",\"index\":7,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852052\",\"statuteCode\":40},{\"id\":\"HME447045\",\"index\":8,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852102\",\"statuteCode\":40},{\"id\":\"HME447046\",\"index\":9,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852394\",\"statuteCode\":40},{\"id\":\"HME447047\",\"index\":10,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852402\",\"statuteCode\":40},{\"id\":\"HME447048\",\"index\":11,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852045\",\"statuteCode\":40},{\"id\":\"HME447049\",\"index\":12,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852149\",\"statuteCode\":40},{\"id\":\"HME447050\",\"index\":13,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852442\",\"statuteCode\":40},{\"id\":\"HME447051\",\"index\":14,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852031\",\"statuteCode\":40},{\"id\":\"HME447052\",\"index\":15,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852047\",\"statuteCode\":40},{\"id\":\"HME447053\",\"index\":16,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852349\",\"statuteCode\":40},{\"id\":\"HME447054\",\"index\":17,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852062\",\"statuteCode\":40},{\"id\":\"HME447055\",\"index\":18,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852043\",\"statuteCode\":40},{\"id\":\"HME447056\",\"index\":19,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852409\",\"statuteCode\":40},{\"id\":\"HME447057\",\"index\":20,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852184\",\"statuteCode\":40},{\"id\":\"HME447058\",\"index\":21,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852419\",\"statuteCode\":40},{\"id\":\"HME447059\",\"index\":22,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852293\",\"statuteCode\":40},{\"id\":\"HME447060\",\"index\":23,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852317\",\"statuteCode\":40},{\"id\":\"HME447061\",\"index\":24,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852373\",\"statuteCode\":40},{\"id\":\"HME447062\",\"index\":25,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852298\",\"statuteCode\":40},{\"id\":\"HME447063\",\"index\":26,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852434\",\"statuteCode\":40},{\"id\":\"HME447064\",\"index\":27,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852320\",\"statuteCode\":40},{\"id\":\"HME447065\",\"index\":28,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852314\",\"statuteCode\":40},{\"id\":\"HME447066\",\"index\":29,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852424\",\"statuteCode\":40},{\"id\":\"HME447067\",\"index\":30,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852439\",\"statuteCode\":40}],\"serial\":\"136800044\",\"service\":18,\"timeout\":5000,\"type\":\"集中器\"}";
        String nodeLists = "[{\"id\":\"HME447006\",\"index\":31,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852227\",\"statuteCode\":40},{\"id\":\"HME447007\",\"index\":32,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852366\",\"statuteCode\":40},{\"id\":\"HME447008\",\"index\":33,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"21200266\",\"statuteCode\":40},{\"id\":\"HME447009\",\"index\":34,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22851093\",\"statuteCode\":40},{\"id\":\"HME447010\",\"index\":35,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852417\",\"statuteCode\":40},{\"id\":\"HME447011\",\"index\":36,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852207\",\"statuteCode\":40},{\"id\":\"HME447012\",\"index\":37,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852055\",\"statuteCode\":40},{\"id\":\"HME447013\",\"index\":38,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852331\",\"statuteCode\":40},{\"id\":\"HME447014\",\"index\":39,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852297\",\"statuteCode\":40},{\"id\":\"HME447015\",\"index\":40,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852369\",\"statuteCode\":40},{\"id\":\"HME447016\",\"index\":41,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852198\",\"statuteCode\":40},{\"id\":\"HME447017\",\"index\":42,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852341\",\"statuteCode\":40},{\"id\":\"HME447018\",\"index\":43,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852151\",\"statuteCode\":40},{\"id\":\"HME447019\",\"index\":44,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852405\",\"statuteCode\":40},{\"id\":\"HME447020\",\"index\":45,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852344\",\"statuteCode\":40},{\"id\":\"HME447021\",\"index\":46,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852305\",\"statuteCode\":40},{\"id\":\"HME447022\",\"index\":47,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852398\",\"statuteCode\":40},{\"id\":\"HME447023\",\"index\":48,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852192\",\"statuteCode\":40},{\"id\":\"HME447024\",\"index\":49,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852295\",\"statuteCode\":40},{\"id\":\"HME447025\",\"index\":50,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852403\",\"statuteCode\":40},{\"id\":\"HME447026\",\"index\":51,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852352\",\"statuteCode\":40},{\"id\":\"HME447027\",\"index\":52,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852393\",\"statuteCode\":40},{\"id\":\"HME447028\",\"index\":53,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852418\",\"statuteCode\":40},{\"id\":\"HME447029\",\"index\":54,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852416\",\"statuteCode\":40},{\"id\":\"HME447030\",\"index\":55,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852368\",\"statuteCode\":40},{\"id\":\"HME447031\",\"index\":56,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852069\",\"statuteCode\":40},{\"id\":\"HME447032\",\"index\":57,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852356\",\"statuteCode\":40},{\"id\":\"HME447033\",\"index\":58,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852167\",\"statuteCode\":40},{\"id\":\"HME447034\",\"index\":59,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852436\",\"statuteCode\":40},{\"id\":\"HME447035\",\"index\":60,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852042\",\"statuteCode\":40},{\"id\":\"HME447036\",\"index\":61,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852050\",\"statuteCode\":40},{\"id\":\"HME447037\",\"index\":62,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852289\",\"statuteCode\":40},{\"id\":\"HME447038\",\"index\":1,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852150\",\"statuteCode\":40},{\"id\":\"HME447039\",\"index\":2,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852200\",\"statuteCode\":40},{\"id\":\"HME447040\",\"index\":3,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852003\",\"statuteCode\":40},{\"id\":\"HME447041\",\"index\":4,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852104\",\"statuteCode\":40},{\"id\":\"HME447042\",\"index\":5,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852354\",\"statuteCode\":40},{\"id\":\"HME447043\",\"index\":6,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852083\",\"statuteCode\":40},{\"id\":\"HME447044\",\"index\":7,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852052\",\"statuteCode\":40},{\"id\":\"HME447045\",\"index\":8,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852102\",\"statuteCode\":40},{\"id\":\"HME447046\",\"index\":9,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852394\",\"statuteCode\":40},{\"id\":\"HME447047\",\"index\":10,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852402\",\"statuteCode\":40},{\"id\":\"HME447048\",\"index\":11,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852045\",\"statuteCode\":40},{\"id\":\"HME447049\",\"index\":12,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852149\",\"statuteCode\":40},{\"id\":\"HME447050\",\"index\":13,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852442\",\"statuteCode\":40},{\"id\":\"HME447051\",\"index\":14,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852031\",\"statuteCode\":40},{\"id\":\"HME447052\",\"index\":15,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852047\",\"statuteCode\":40},{\"id\":\"HME447053\",\"index\":16,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852349\",\"statuteCode\":40},{\"id\":\"HME447054\",\"index\":17,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852062\",\"statuteCode\":40},{\"id\":\"HME447055\",\"index\":18,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852043\",\"statuteCode\":40},{\"id\":\"HME447056\",\"index\":19,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852409\",\"statuteCode\":40},{\"id\":\"HME447057\",\"index\":20,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852184\",\"statuteCode\":40},{\"id\":\"HME447058\",\"index\":21,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852419\",\"statuteCode\":40},{\"id\":\"HME447059\",\"index\":22,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852293\",\"statuteCode\":40},{\"id\":\"HME447060\",\"index\":23,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852317\",\"statuteCode\":40},{\"id\":\"HME447061\",\"index\":24,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852373\",\"statuteCode\":40},{\"id\":\"HME447062\",\"index\":25,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852298\",\"statuteCode\":40},{\"id\":\"HME447063\",\"index\":26,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852434\",\"statuteCode\":40},{\"id\":\"HME447064\",\"index\":27,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852320\",\"statuteCode\":40},{\"id\":\"HME447065\",\"index\":28,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852314\",\"statuteCode\":40},{\"id\":\"HME447066\",\"index\":29,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852424\",\"statuteCode\":40},{\"id\":\"HME447067\",\"index\":30,\"model\":\"DN25\",\"port\":4,\"region\":\"户\",\"serial\":\"22852439\",\"statuteCode\":40}]";
        CommNetEquipment commNetEquipment = JSON.parseObject(s, CommNetEquipment.class);
        List<Node> nodeList = new ArrayList<>(JSON.parseArray(nodeLists, Meter.class));
        commNetEquipment.setNodeList(nodeList);
        log.info("抄表：{}", commNetEquipment.getNodeList().stream().map(Node::getSerial).collect(Collectors.joining(",")));

    }



    public void readRunaMeters(List<MeterBase> meterBases, String taskNo, String holdInfo, Integer priority) {
        if (CollectionUtil.isEmpty(meterBases)) {
            return;
        }
        List<RunaMeter> runaMeters = meterBases.stream().map(v -> (RunaMeter) v).collect(Collectors.toList());
        Map<Integer, List<String>> runaMeterMap = runaMeters.stream().collect(Collectors.groupingBy(RunaMeter::getCommType, Collectors.mapping(RunaMeter::getMeter, Collectors.toList())));
        for (Integer commType : runaMeterMap.keySet()) {
            List<String> meterIds = runaMeterMap.get(commType);
            switch (commType) {
                case 3:
                    // NB
                    break;
                case 6:
                    // 4G直供
                    break;
                default:
                    readMeter(taskNo, holdInfo, meterIds, priority);
            }
        }
    }

    public void readMeter(String taskNo, String holdInfo, List<String> nodeIdentityList, Integer priority) {
        List<CommNetEquipment> commNetEquipmentList = batchQueryMeter(taskNo, holdInfo, nodeIdentityList);
        LogUtil.getLogAndInfo("readMeter", "抄表", "{} {}", taskNo, JSON.toJSONString(commNetEquipmentList));
        for (CommNetEquipment commNetEquipment : commNetEquipmentList) {
            try {
                LogUtil.getLogAndInfo("表所属网络设备", "抄表", "{} {}", taskNo, JSON.toJSONString(commNetEquipment));
                LogUtil.info(commNetEquipment.getSerial(), "{} 抄表：{}", taskNo, commNetEquipment.getNodeList().stream().map(Node::getSerial).collect(Collectors.joining(",")));
                if (NetEquTypeEnum.AI控制器.equals(commNetEquipment.getType())) {
                    buildGatewayService.rccReadNodeData(taskNo, holdInfo, commNetEquipment.getNodeList(), commNetEquipment, HotMeterVO.TOPIC);
                } else {
                    netEquService.readNodeEquipment(commNetEquipment, commNetEquipment.getNodeList(), taskNo, holdInfo, EquData.EquDataType.METER, priority);
                }
            } catch (Exception e) {
                log.error("表下发队列报错: {} {} ", taskNo, commNetEquipment.getSerial(), e);
            }
        }
    }




    public void readRunaValves(List<ValveBase> valveBases, String taskNo, String holdInfo, Integer priority) {
        if (CollectionUtil.isEmpty(valveBases)) {
            return;
        }
        List<RunaReadValve> runaReadValves = valveBases.stream().map(v -> (RunaReadValve) v).collect(Collectors.toList());
        Map<Integer, List<String>> runaValveMap = runaReadValves.stream().collect(Collectors.groupingBy(RunaReadValve::getCommType, Collectors.mapping(RunaReadValve::getValve, Collectors.toList())));
        for (Integer commType : runaValveMap.keySet()) {
            List<String> valveIds = runaValveMap.get(commType);
            switch (commType) {
                case 3:
                    // NB
                    break;
                case 6:
                    // 4G直供
                    List<Node> nodeList = batchQueryFourGValve(taskNo, holdInfo, valveIds);
                    readFourGValves(nodeList, taskNo, holdInfo, priority);
                    break;
                default:
                    readValve(taskNo, holdInfo, valveIds, priority);
            }
        }
    }

    public void readValve(String taskNo, String holdInfo, List<String> nodeIdentityList, Integer priority) {
        BatchValveDTO batchValveDTO = batchQueryValve(taskNo, holdInfo, nodeIdentityList);
        LogUtil.getLogAndInfo("readValve", "抄阀", "{} {}", taskNo, JSON.toJSONString(batchValveDTO));
        for (CommNetEquipment commNetEquipment : batchValveDTO.getCommNetEquipmentList()) {
            try {
                LogUtil.getLogAndInfo("阀所属网络设备", "抄阀", "{} {}", taskNo, JSON.toJSONString(commNetEquipment));
                LogUtil.info(commNetEquipment.getSerial(), "{} 抄阀：{}", taskNo, commNetEquipment.getNodeList().stream().map(Node::getSerial).collect(Collectors.joining(",")));
                if (NetEquTypeEnum.AI控制器.equals(commNetEquipment.getType())) {
                    buildGatewayService.rccReadNodeData(taskNo, holdInfo, commNetEquipment.getNodeList(), commNetEquipment, ValveVO.TOPIC);
                } else {
                    netEquService.readNodeEquipment(commNetEquipment,
                            commNetEquipment.getNodeList().stream().filter(node -> {
                                Valve valve = (Valve) node;
                                return RegionTypeEnum.户.equals(valve.getRegion());
                            }).collect(Collectors.toList()), taskNo, holdInfo, EquData.EquDataType.VALVE, priority);
                    netEquService.readNodeEquipment(commNetEquipment,
                            commNetEquipment.getNodeList().stream().filter(node -> {
                                Valve valve = (Valve) node;
                                return RegionTypeEnum.楼.equals(valve.getRegion());
                            }).collect(Collectors.toList()), taskNo, holdInfo, EquData.EquDataType.PUBLIC_UNIT, priority);
                }
            } catch (Exception e) {
                log.error("阀下发队列报错: {} {} ", taskNo, commNetEquipment.getSerial(), e);
            }
        }
        readFourGValves(batchValveDTO.getFourGValves(), taskNo, holdInfo, priority);
    }

    private void readFourGValves(List<Node> fourGValves, String taskNo, String holdInfo, Integer priority) {
        for (Node node : fourGValves) {
            fourGValveDtuService.addTask(node, taskNo, holdInfo, priority);
        }
    }

    public void readPanel(String taskNo, String holdInfo, List<String> nodeIdentityList, Integer priority) {
        List<CommNetEquipment> netEquipments = batchQueryPanel(taskNo, holdInfo, nodeIdentityList);
        for (CommNetEquipment commNetEquipment : netEquipments) {
            if (NetEquTypeEnum.AI控制器.equals(commNetEquipment.getType())) {
                buildGatewayService.rccReadNodeData(taskNo, holdInfo, commNetEquipment.getNodeList(), commNetEquipment, PanelVO.TOPIC);
            } else {
                netEquService.readNodeEquipment(commNetEquipment,
                        commNetEquipment.getNodeList(), taskNo, holdInfo, EquData.EquDataType.TEMPERATURE_PANEL, priority);
            }
        }
    }


    public void rccReadNodeDataOfElec(String identity, String taskNo, String holdInfo) {
        CommNetEquipment commNetEquipment = repositoryService.getCommNetEquipmentByIdentity(identity);
        if (commNetEquipment == null) {
            log.error("无此档案:" + identity);
            MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, MqttUtil.topicOfNoneContent, identity);
            return;
        }
        netEquService.readElectricityMeter(commNetEquipment);
    }

    //读楼站阀四大参数
    public void buildValveParam(String taskNo, List<String> nodeIdentityList, Integer model, String holdInfo, Integer priority) {
        List<CommNetEquipment> commNetEquipmentList = batchValve(taskNo, holdInfo, nodeIdentityList);
        for (CommNetEquipment commNetEquipment : commNetEquipmentList) {
            for (Node node : commNetEquipment.getNodeList()) {
                netEquService.buildValveParam(commNetEquipment, taskNo, holdInfo, priority, node, model);
            }
        }
    }


    //外部统一入口
    //四大楼站功能参数下发   楼参数(新接口外部部分独立)   节假日(新接口外部独立)   PID(新接口外部独立)  上下限(新接口外部独立)
    public void valveControl(String taskNo, String holdInfo, List<ValveControl> valveControlList, Integer priority) {
        List<String> list = valveControlList.stream().map(ValveControl::getValve).collect(Collectors.toList());
        List<CommNetEquipment> commNetEquipmentList = batchValve(taskNo, holdInfo, list);
        for (CommNetEquipment commNetEquipment : commNetEquipmentList) {
            if (NetEquTypeEnum.AI控制器.equals(commNetEquipment.getType())) {
                for (Node node : commNetEquipment.getNodeList()) {
                    Optional<CommValve> commValve = commValveRepository.findById(node.getId());
                    if (commValve.isPresent()) {
                        ValveControl valveControl = valveControlList.stream().filter(vc ->
                                commValve.get().getId().equals(vc.getValve())).findFirst().get();
                        if (RegionTypeEnum.户.equals(commValve.get().getRegion())) {
                            if (ValveControl.TypeEnum.开度.equals(valveControl.getType())) {
                                buildGatewayService.valveOnOffControl(taskNo, holdInfo, Collections.singletonList(node),
                                        commNetEquipment, valveControl.getLock(), valveControl.getValue().intValue(), MqttUtil.topicOfNoneContentForNode);
                            }
                            if (ValveControl.TypeEnum.室温.equals(valveControl.getType())) {
                                buildGatewayService.valveTemperatureControl(taskNo, holdInfo, Collections.singletonList(node), commNetEquipment,
                                        valveControl.getValue(), valveControl.getLock(), null, null, MqttUtil.topicOfNoneContentForNode);
                            }
                        } else {
                            buildGatewayService.buildValveControl(taskNo, holdInfo, Collections.singletonList(node),
                                    commNetEquipment, valveControl.getValue().toString(), MqttUtil.topicOfNoneContentForNode);
                        }
                    }
                }
            } else {
                for (Node node : commNetEquipment.getNodeList()) {
                    Optional<CommValve> commValve = commValveRepository.findById(node.getId());
                    if (commValve.isPresent()) {
                        ValveControl valveControl = valveControlList.stream().filter(vc ->
                                commValve.get().getId().equals(vc.getValve())).findFirst().get();
                        if (RegionTypeEnum.户.equals(commValve.get().getRegion())) {
                            if (ValveControl.TypeEnum.开度.equals(valveControl.getType())) {
                                netEquService.valveOnOffControl(commNetEquipment,
                                        taskNo, holdInfo, priority, Collections.singletonList(node),
                                        valveControl.getValue().intValue(), valveControl.getLock());
                            }
                            if (ValveControl.TypeEnum.室温.equals(valveControl.getType())) {
                                netEquService.valveTemperatureControl(commNetEquipment,
                                        taskNo, holdInfo, priority, Collections.singletonList(node),
                                        valveControl.getValue().intValue(), valveControl.getLock());
                            }
                        }
                        if (RegionTypeEnum.楼.equals(commValve.get().getRegion())) {
                            Map<String, Object> param = new HashMap<>();
                            param.put("controlObject", valveControl.getType().toString());
                            param.put("targetValue", valveControl.getValue());
                            netEquService.sentPublicUnitRecord(commNetEquipment, taskNo,
                                    holdInfo, priority, Collections.singletonList(node), 1, param);
                        }
                    } else {
                        MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, MqttUtil.topicOfNoneContent, node.getId());
                    }
                }
            }
        }

    }

    public void buildValveModelOfPID(String taskNo, String holdInfo, ValvePID valvePID, Integer priority) {
        //先行验证
        CommValve commValve = repositoryService.getCommValveByNodeIdentity(valvePID.getValve());
        if (commValve == null) {
            log.error("无此档案:" + valvePID.getValve());
            MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, MqttUtil.topicOfNoneContent, valvePID.getValve());
            return;
        }
        CommNetEquipment commNetEquipment = repositoryService.getCommNetEquipmentByIdentity(commValve.getNetEquipmentId());

        Map<String, Object> param = new HashMap();
        param.put("P", valvePID.getP());
        param.put("I", valvePID.getI());
        param.put("D", valvePID.getD());
        HashMap<String, Object> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("PID", param);
        netEquService.sentPublicUnitRecord(commNetEquipment, taskNo,
                holdInfo, priority, Collections.singletonList(Valve.getValve(commValve)), 3, param);
    }

    public void buildValveOpenLimit(String taskNo, String holdInfo, List<com.runa.monitor.platinterface.dispatch.conn.gen.ValveOpenLimit> valveOpenLimitList, Integer priority) {
        for (ValveOpenLimit valveOpenLimit : valveOpenLimitList) {
            CommValve commValve = repositoryService.getCommValveByNodeIdentity(valveOpenLimit.getValve());
            if (commValve == null) {
                log.error("无此档案:" + valveOpenLimit.getValve());
                MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, MqttUtil.topicOfNoneContent, valveOpenLimit.getValve());
                return;
            }
            CommNetEquipment commNetEquipment = repositoryService.getCommNetEquipmentByIdentity(commValve.getNetEquipmentId());
            Map<String, Object> param = new HashMap<>();
            param.put("valveUp", valveOpenLimit.getUp());
            param.put("valveDown", valveOpenLimit.getDown());
            HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
            objectObjectHashMap.put("valveUpDown", param);
            netEquService.sentPublicUnitRecord(commNetEquipment, taskNo,
                    holdInfo, priority, Collections.singletonList(Valve.getValve(commValve)), 4, param);
        }
    }


    public void houseValveSetTempSnOfAiStorm(HouseValveControlPOJO houseValveControlPOJO) {
        CommValve commValve = repositoryService.getCommValveByNodeIdentity(houseValveControlPOJO.getValve());
        if (commValve == null) {
            MqttUtil.sendOfWithoutArchive(houseValveControlPOJO.getTask(), houseValveControlPOJO.getHoldInfo(), ValveVO.TOPIC, houseValveControlPOJO.getValve());
            return;
        }
        CommNetEquipment commNetEquipment = repositoryService.getCommNetEquipmentByIdentity(commValve.getNetEquipmentId());
        buildGatewayService.houseValveSetValveTempSn(houseValveControlPOJO.getTask(),
                houseValveControlPOJO.getHoldInfo(), commNetEquipment, MqttUtil.topicOfNoneContentForNode);
    }


    public void houseValveSetValveTempSnOfAiStorm(HouseValveControlPOJO houseValveControlPOJO) {
        CommNetEquipment commNetEquipment = repositoryService.getCommNetEquipmentByNetSerial(houseValveControlPOJO.getNetSerial());
        buildGatewayService.houseValveSetValveTempSn(houseValveControlPOJO.getTask()
                , houseValveControlPOJO.getHoldInfo(), commNetEquipment, MqttUtil.topicOfNoneContentForNode);
    }

    public void houseValveSetRlOfAiStorm(HouseValveControlPOJO houseValveControlPOJO) {
        CommValve commValve = repositoryService.getCommValveByNodeIdentity(houseValveControlPOJO.getValve());
        if (commValve == null) {
            MqttUtil.sendOfWithoutArchive(houseValveControlPOJO.getTask(), houseValveControlPOJO.getHoldInfo(), ValveVO.TOPIC, houseValveControlPOJO.getValve());
            return;
        }
        Valve valve = Valve.getValve(commValve);
        CommNetEquipment commNetEquipment = repositoryService.getCommNetEquipmentByIdentity(commValve.getNetEquipmentId());
        buildGatewayService.houseValveSetRl( houseValveControlPOJO.getTask(), houseValveControlPOJO.getHoldInfo(),
                Collections.singletonList(valve), commNetEquipment, houseValveControlPOJO.getAccHeat(), MqttUtil.topicOfNoneContentForNode);
    }

    @Resource
    private FlightControlService flightControlService;

    public void valveTemperatureControlOfAiStorm(ValveTemperatureControlOfAiStorm valveTemperatureControlOfAiStorm, Integer priority) {
        //先行验证
        List<TemperatureControl> temperatureControlList = valveTemperatureControlOfAiStorm.getTemperatureControlList();
        for (TemperatureControl temperatureControl : temperatureControlList) {
            CommValve commValve = repositoryService.getCommValveByNodeIdentity(temperatureControl.getValve());
            if (commValve == null) {
                MqttUtil.sendOfWithoutArchive(valveTemperatureControlOfAiStorm.getTask(), valveTemperatureControlOfAiStorm.getHoldInfo(), ValveVO.TOPIC, temperatureControl.getValve());
                return;
            }
            CommNetEquipment commNetEquipment = repositoryService.getCommNetEquipmentByIdentity(commValve.getNetEquipmentId());
            buildGatewayService.valveTemperatureControl(valveTemperatureControlOfAiStorm.getTask()
                    , valveTemperatureControlOfAiStorm.getHoldInfo()
                    , Collections.singletonList(Valve.getValve(commValve)), commNetEquipment, temperatureControl.getTemperature()
                    , temperatureControl.getLock(), temperatureControl.getUp()
                    , temperatureControl.getDown(), MqttUtil.topicOfNoneContentForNode);
        }

    }


    //户阀温度补偿
    public void valveTemperatureComp(String taskNo, String holdInfo, String valveSerial, Float temperature, Integer priority) {
        CommValve commValve = repositoryService.getCommValveByNodeIdentity(valveSerial);
        if (commValve == null) {
            MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, ValveVO.TOPIC, valveSerial);
            return;
        }
        CommNetEquipment commNetEquipment = repositoryService.getCommNetEquipmentByIdentity(commValve.getNetEquipmentId());
        Valve valve = Valve.getValve(commValve);
        netEquService.temperatureCompensation(commNetEquipment, taskNo, holdInfo, priority, Collections.singletonList(valve), temperature);
    }

    //网络设备下楼站阀门远程/本地模式切换控制
    public void buildValveModel(String taskNo, String holdInfo, String id, boolean model, Integer priority) {
        CommValve commValve = repositoryService.getCommValveByNodeIdentity(id);
        if (commValve == null) {
            MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, ValveVO.TOPIC, id);
            return;
        }
        CommNetEquipment commNetEquipment = repositoryService.getCommNetEquipmentByIdentity(commValve.getNetEquipmentId());
        netEquService.sentPublicUnitModel(commNetEquipment, taskNo, holdInfo, priority, Collections.singletonList(Valve.getValve(commValve)), model);
    }

    public void meterDownloadFile(String task, String holdInfo, AiDownloadFile aiDownloadFile) {
        //先行验证
        CommNetEquipment commNetEquipment = repositoryService.getCommNetEquipmentByIdentity(aiDownloadFile.getGwId());
        if (commNetEquipment == null) {
            MqttUtil.sendOfWithoutArchive(task, holdInfo, "aistorm/build/resp", aiDownloadFile.getGwId());
            return;
        }
        buildGatewayService.meterDownloadFile(task, holdInfo, commNetEquipment, aiDownloadFile.getPath(), aiDownloadFile.getMd5(), MqttUtil.topicOfNoneContent);
    }


    public void valveTemperatureControl(String taskNo, String holdInfo, List<ValveTemperatureLimit> valveTemperatureLimits, Integer priority) {
        List<String> list = valveTemperatureLimits.stream().map(ValveTemperatureLimit::getValve).collect(Collectors.toList());
        List<CommNetEquipment> commNetEquipmentList = batchValve(taskNo, holdInfo, list);
        for (CommNetEquipment commNetEquipment : commNetEquipmentList) {
            if (NetEquTypeEnum.AI控制器.equals(commNetEquipment.getType())) {
                for (ValveTemperatureLimit limit : valveTemperatureLimits) {
                    Optional<Node> valve = commNetEquipment.getNodeList().stream()
                            .filter(node -> node.getId().equals(limit.getValve())).findFirst();
                    if (valve.isPresent()) {
                        buildGatewayService.valveTemperatureControl(taskNo, holdInfo, commNetEquipment.getNodeList(),
                                commNetEquipment, null, null, limit.getUp(), limit.getDown(), MqttUtil.topicOfNoneContentForNode);
                    }
                }
            } else {
                for (ValveTemperatureLimit limit : valveTemperatureLimits) {
                    Optional<Node> valve = commNetEquipment.getNodeList().stream()
                            .filter(node -> node.getId().equals(limit.getValve())).findFirst();
                    if (valve.isPresent()) {
                        netEquService.valveTemperatureLimit(commNetEquipment, taskNo, holdInfo,
                                priority, Collections.singletonList(valve.get()), limit.getUp(), limit.getDown());
                    } else {
                        MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, MqttUtil.topicOfNoneContent, limit.getValve());
                    }
                }
            }
        }
    }

    public void runaValveControl(List<ValveBase> valveBases, String taskNo, String holdInfo, Integer priority) {
        List<RunaValve> runaValves = new ArrayList<>();
        for (ValveBase valveBase : valveBases) {
            if (!(valveBase instanceof RunaValve)) {
                log.error("控阀参数错误: {} {}", taskNo, JSON.toJSONString(valveBase));
                continue;
            }
            runaValves.add((RunaValve)valveBase);
        }
        Map<Integer, List<RunaValve>> runaValveMap = runaValves.stream().collect(Collectors.groupingBy(RunaValve::getCommType));
        for (Integer commType : runaValveMap.keySet()) {
            switch(commType) {
                case 1:
                case 2:
                case 4:
                    // 集中器阀控
                    concentratorValveControl(runaValveMap.get(commType), taskNo, holdInfo, priority);
                    break;
                case 3:
                    // NB
                case 5:
                    // 4G电池
                    runaNbControl(runaValveMap.get(commType), taskNo, holdInfo, priority);
                    break;
                case 6:
                    // 4G 直供电
                    runaFourGValveControl(runaValveMap.get(commType), taskNo, holdInfo, priority);
                    break;

            }
        }
    }


    public void zheDaValveControl(List<ValveBase> valveBases, String taskNo, String holdInfo, Integer priority) {
        Map<String, ApportionValveControlParam> valveMap = new HashMap<>();
        List<String> valveIds = new ArrayList<>();
        for (ValveBase valveBase : valveBases) {
            if (!(valveBase instanceof ZheDaValve)) {
                log.error("哲达控阀参数错误: {} {}", taskNo, JSON.toJSONString(valveBase));
                continue;
            }
            ZheDaValve zheDaValve = (ZheDaValve)valveBase;
            valveMap.put(zheDaValve.getNodeId(), ApportionValveControlParam.getInstance(zheDaValve));
            valveIds.add(zheDaValve.getNodeId());
        }
        apportionValveControl(valveMap, valveIds,  taskNo, holdInfo, priority);
    }

    public void yiLinValveControl(List<ValveBase> valveBases, String taskNo, String holdInfo, Integer priority) {
        Map<String, ApportionValveControlParam> valveMap = new HashMap<>();
        List<String> valveIds = new ArrayList<>();
        for (ValveBase valveBase : valveBases) {
            if (!(valveBase instanceof YiLinValve)) {
                log.error("亿林控阀参数错误: {} {}", taskNo, JSON.toJSONString(valveBase));
                continue;
            }
            YiLinValve yiLinValve = (YiLinValve)valveBase;
            valveMap.put(yiLinValve.getNodeId(), ApportionValveControlParam.getInstance(yiLinValve));
            valveIds.add(yiLinValve.getNodeId());
        }
        apportionValveControl(valveMap, valveIds,  taskNo, holdInfo, priority);
    }

    public void apportionValveControl(Map<String, ApportionValveControlParam> valveMap, List<String> valveIds, String taskNo, String holdInfo, Integer priority) {
        List<CommNetEquipment> commNetEquipmentList = batchValve(taskNo, holdInfo, valveIds);
        if (CollectionUtil.isEmpty(commNetEquipmentList)) {
            return;
        }
        for (CommNetEquipment commNetEquipment : commNetEquipmentList) {
            for (Node node : commNetEquipment.getNodeList()) {
                ApportionValveControlParam apportionValveControl = valveMap.get(node.getId());
                apportionValveControl.setNode(node);
                netEquService.valveOnOffControl(commNetEquipment, apportionValveControl, taskNo, holdInfo, priority);
            }
        }
    }

    @Resource
    private CommNbCmdService commandsService;

    private void runaNbControl(List<RunaValve> runaValves, String taskNo, String holdInfo, Integer priority) {
        for (RunaValve runaValve : runaValves) {
            String type = runaValve.getType();
            String valveId = runaValve.getValve();
            ValveControl.TypeEnum typeEnum = ValveControl.TypeEnum.valueOf(type);
            NBOrder nbOrder = new NBOrder();
            switch (typeEnum) {
                case 开度:
                    nbOrder.setOpen(String.valueOf(runaValve.getValue()));
                    commandsService.addNbOrder(valveId, nbOrder);
                    break;
                case 唤醒周期:
                    nbOrder.setWakeupCycle(String.valueOf((int)runaValve.getValue()));
                    commandsService.addNbOrder(valveId, nbOrder);
                    break;
                case 温度补偿:
                    nbOrder.setCompensation(String.valueOf(runaValve.getValue()));
                    commandsService.addNbOrder(valveId, nbOrder);
                    break;
            }
            AsynResult asynResult = new AsynResult();
            asynResult.setCode(ResultConstants.CODE_200);
            asynResult.setMsg(MqttUtil.successString);
            asynResult.setTask(taskNo);
            asynResult.setHoldInfo(holdInfo);
            asynResult.setIdentity(valveId);
            MqttUtil.send(MqttUtil.topicOfNoneContent, asynResult);
        }

    }

    @Resource
    private FourGValveDtuService fourGValveDtuService;

    public void runaFourGValveControl(List<RunaValve> runaValves, String taskNo, String holdInfo, Integer priority) {
        List<String> valveSerials = runaValves.stream().map(RunaValve::getValve).distinct().collect(Collectors.toList());
        ArrayList<String> nodeIds = new ArrayList<>(valveSerials.stream().distinct().collect(Collectors.toList()));
        List<CommValve> valves = commValveService.getAllByIds(nodeIds);
        List<String> meterIds = valves.stream().map(CommValve::getId).collect(Collectors.toList());
        for (String meterId : meterIds) {
            nodeIds.remove(meterId);
        }
        if (!nodeIds.isEmpty())
            nodeIds.forEach(s -> MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, ValveVO.TOPIC, s));
        if (valves.isEmpty()) return;

        Map<String, List<RunaValve>> runaValveMap = runaValves.stream().collect(Collectors.groupingBy(RunaValve::getValve));
        for (CommValve commValve : valves) {
            List<RunaValve> runaValvesList = runaValveMap.get(commValve.getId());
            if (CollectionUtil.isNotEmpty(runaValvesList)) {
                fourGValveDtuService.addWriteTask(Valve.getValve(commValve), runaValvesList.get(0), taskNo, holdInfo, priority);
            }
        }
    }

    public void concentratorValveControl(List<RunaValve> runaValves, String taskNo, String holdInfo, Integer priority) {
        List<String> valveIds = runaValves.stream().map(RunaValve::getValve).distinct().collect(Collectors.toList());
        List<CommNetEquipment> commNetEquipmentList = batchValve(taskNo, holdInfo, valveIds);
        if (CollectionUtil.isEmpty(commNetEquipmentList)) {
            return;
        }
        for (CommNetEquipment commNetEquipment : commNetEquipmentList) {
            if (NetEquTypeEnum.AI控制器.equals(commNetEquipment.getType())) {
                for (Node node : commNetEquipment.getNodeList()) {
                    Optional<CommValve> commValve = commValveRepository.findById(node.getId());
                    if (commValve.isPresent()) {
                        RunaValve valveControl = runaValves.stream().filter(vc ->
                                commValve.get().getId().equals(vc.getValve())).findFirst().get();
                        if (RegionTypeEnum.户.equals(commValve.get().getRegion())) {
                            if (ValveControl.TypeEnum.开度.name().equals(valveControl.getType())) {
                                buildGatewayService.valveOnOffControl(taskNo, holdInfo, Collections.singletonList(node),
                                        commNetEquipment, valveControl.isLock(), (int) valveControl.getValue(), MqttUtil.topicOfNoneContentForNode);
                            }
                            if (ValveControl.TypeEnum.室温.name().equals(valveControl.getType())) {
                                buildGatewayService.valveTemperatureControl(taskNo, holdInfo, Collections.singletonList(node), commNetEquipment,
                                        (float) valveControl.getValue(), valveControl.isLock(), null, null, MqttUtil.topicOfNoneContentForNode);
                            }
                            if (ValveControl.TypeEnum.温度范围.name().equals(valveControl.getType())) {
                                buildGatewayService.valveTemperatureControl(taskNo, holdInfo, Collections.singletonList(node), commNetEquipment,
                                    (float) valveControl.getValue(), valveControl.isLock(), (float)valveControl.getValue(), valveControl.getAttachValue().floatValue(), MqttUtil.topicOfNoneContentForNode);
                            }
                        } else {
                            buildGatewayService.buildValveControl(taskNo, holdInfo, Collections.singletonList(node),
                                    commNetEquipment, String.valueOf(valveControl.getValue()), MqttUtil.topicOfNoneContentForNode);
                        }
                    }
                }
            } else {
                for (Node node : commNetEquipment.getNodeList()) {
                    Optional<CommValve> commValve = commValveRepository.findById(node.getId());
                    if (commValve.isPresent()) {
                        RunaValve valveControl = runaValves.stream().filter(vc ->
                                commValve.get().getId().equals(vc.getValve())).findFirst().get();
                        if (RegionTypeEnum.户.equals(commValve.get().getRegion())) {
                            if (ValveControl.TypeEnum.开度.name().equals(valveControl.getType())) {
                                netEquService.valveOnOffControl(commNetEquipment,
                                        taskNo, holdInfo, priority, Collections.singletonList(node),
                                        (int) valveControl.getValue(), valveControl.isLock());
                            }
                            if (ValveControl.TypeEnum.室温.name().equals(valveControl.getType())) {
                                netEquService.valveTemperatureControl(commNetEquipment,
                                        taskNo, holdInfo, priority, Collections.singletonList(node),
                                        (int) valveControl.getValue(), valveControl.isLock());
                            }
                            if (ValveControl.TypeEnum.温度范围.name().equals(valveControl.getType())) {
                                netEquService.valveTemperatureLimit(commNetEquipment,
                                        taskNo, holdInfo, priority, Collections.singletonList(node),
                                        (float) valveControl.getValue(), valveControl.getAttachValue().floatValue());
                            }
                        }
                        if (RegionTypeEnum.楼.equals(commValve.get().getRegion())) {
                            Map<String, Object> param = new HashMap<>();
                            param.put("controlObject", valveControl.getType());
                            param.put("targetValue", valveControl.getValue());
                            netEquService.sentPublicUnitRecord(commNetEquipment, taskNo,
                                    holdInfo, priority, Collections.singletonList(node), 1, param);
                        }
                    } else {
                        MqttUtil.sendOfWithoutArchive(taskNo, holdInfo, MqttUtil.topicOfNoneContent, node.getId());
                    }
                }
            }
        }
    }

    public void flightControlValveControl(List<ValveBase> valveBases, String task, String holdInfo, Integer priority) {
        try {
            flightControlService.send(valveBases, task, holdInfo, priority);
        } catch (Exception e) {
            log.error("", e);
        }
    }

    @Resource
    private HmyValveService hmyValveService;

    public void hmyValveControl(List<ValveBase> valveBases, String task, String holdInfo, Integer priority) {
        try {
            hmyValveService.send(valveBases, task, holdInfo, priority);
        } catch (Exception e) {
            log.error("", e);
        }
    }


}
